package com.zpark.mq.t1;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * 消费者：消费（获取）队列当中的消息
 */
public class Consumer {
    public static void main(String[] args) throws Exception {
        // 创建连接工厂对象
        ConnectionFactory factory = new ConnectionFactory();
        // 设置连接消息
        factory.setHost("localhost");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");

        // 创建与RabbitMQ服务的TCP连接
        Connection conn = factory.newConnection();

        // 创建与Exchange的通道，每个连接可以创建多个通道，每个通道代表一个会话任务
        Channel channel = conn.createChannel();

        // 声明队列
        /**
         * 声明队列，如果Rabbit中没有此队列将自动创建
         * param1:队列名称
         * param2:是否持久化
         * param3:队列是否独占此连接
         * param4:队列不再使用时是否自动删除此队列
         * param5:队列参数
         */
        channel.queueDeclare("HelloWorld", true, false,
                true, null);

        // 定义消费方法
        DefaultConsumer consumer = new DefaultConsumer(channel){

            /**
             * 消费者接收消息调用此方法
             * @param consumerTag 消费者的标签，在channel.basicConsume()去指定
             * @param envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志
             *                 (收到消息失败后是否需要重新发送)
             * @param properties
             * @param body 消息体
             * @throws IOException
            }
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                // 获取交换机
                String exchange = envelope.getExchange();
                System.out.println(exchange);
                // 获取路由key
                String routingKey = envelope.getRoutingKey();
                System.out.println(routingKey);
                // 获取消息ID
                long id = envelope.getDeliveryTag();
                System.out.println(id);

                // 获取消息
                String msg = new String(body, "UTF-8");
                System.out.println("消费者获取消息：" + msg);
            }
        };


        /**
         * 监听队列String queue, boolean autoAck,Consumer callback
         * 参数明细
         * 1、队列名称
         * 2、是否自动回复，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置
         为false则需要手动回复
         * 3、消费消息的方法，消费者接收到消息后调用此方法
         */
        channel.basicConsume("HelloWorld", true, consumer);
    }
}
